McAfee’s Mobile Research team recently learned of a new malicious Android application masquerading as a plugin for a transportation application series developed by a South Korean developer. The series provides a range of information for each region of South Korea, such as bus stop locations, bus arrival times and so on. There are a total of four apps in the series, with three of them available from Google Play since 2013 and the other from around 2017. Currently, all four apps have been removed from Google Play while the fake plugin itself was never uploaded to the store. While analyzing the fake plugin, we were looking for initial downloaders and additional payloads – we discovered one specific version of each app in the series (uploaded at the same date) which was dropping malware onto the devices on which they were installed, explaining their removal from Google Play after 5 years of development.
Figure 1. Cached Google Play page of Daegu Bus application, one of the apps in series
When the malicious transportation app is installed, it downloads an additional payload from hacked web servers which includes the fake plugin we originally acquired. After the fake plugin is downloaded and installed, it does something completely different – it acts as a plugin of the transportation application and installs a trojan on the device, trying to phish users to input their Google account password and completely take control of the device. What is interesting is that the malware uses the native library to take over the device and also deletes the library to hide from detection. It uses names of popular South Korean services like Naver, KakaoTalk, Daum and SKT. According to our telemetry data, the number of infected devices was quite low, suggesting that the final payload was installed to only a small group of targets.
The Campaign
The following diagram explains the overall flow from malware distribution to device infection.
Figure 2. Device infection process
When the malicious version of the transportation app is installed, it checks whether the fake plugin is already installed and, if not, downloads from the server and installs it. After that, it downloads and executes an additional native trojan binary which is similar to the trojan which is dropped by the fake plugin. After everything is done, it connects with the C2 servers and handles received commands.
Initial Downloader
The following table shows information about the malicious version of each transportation app in the series. As the Google Play number of install stats shows, these apps have been downloaded on many devices.
Unlike the clean version of the app, the malicious version contains a native library named “libAudio3.0.so”.
Figure 3. Transportation app version with malicious native library embedded
In the BaseMainActivity class of the app, it loads the malicious library and calls startUpdate() and updateApplication().
Figure 4. Malicious library being loaded and executed in the app
startUpdate() checks whether the app is correctly installed by checking for the existence of a specific flag file named “background.png” and whether the fake plugin is installed already. If the device is not already infected, the fake plugin is downloaded from a hacked web server and installed after displaying a toast message to the victim. updateApplication() downloads a native binary from the same hacked server and dynamically loads it. The downloaded file (saved as libSound1.1.so) is then deleted after being loaded into memory and, finally, it executes an exported function which acts as a trojan. As previously explained, this file is similar to the file dropped by the fake plugin which is discussed later in this post.
Figure 5 Additional payload download servers
Fake Plugin
The fake plugin is downloaded from a hacked web server with file extension “.mov” to look like a media file. When it is installed and executed, it displays a toast message saying the plugin was successfully installed (in Korean) and calls a native function named playMovie(). The icon for the fake plugin soon disappears from the screen. The native function implemented in LibMovie.so, which is stored inside the asset folder, drops a malicious trojan to the current running app’s directory masquerading as libpng.2.1.so file. The dropped trojan is originally embedded in the LibMovie.so xor’ed, which is decoded at runtime. After giving permissions, the address of the exported function “Libfunc” in the dropped trojan is dynamically retrieved using dlsym(). The dropped binary in the filesystem is deleted to avoid detection and finally Libfunc is executed.
Figure 6 Toast message when malware is installed
In the other forked process, it tries to access the “naver.property” file on an installed SD Card, if there is one, and if it succeeds, it tries starting “.KaKaoTalk” activity which displays a Google phishing page (more on that in the next section) . The overall flow of the dropper is explained in the following diagram:
Figure 7. Execution flow of the dropper
Following is a snippet of a manifest file showing that “.KaKaoTalk” activity is exported.
Figure 8. Android Manifest defining “.KaKaoTalk” activity as exported
Phishing in JavaScript
KakaoTalk class opens a local HTML file, javapage.html, with the user’s email address registered on the infected device automatically set to log into their account.
Figure 9. KakaoTalk class loads malicious local html file
The victim’s email address is set to the local page through a JavaScript function setEmailAddress after the page is finished loading. A fake Korean Google login website is displayed:
Figure 10. The malicious JavaScript shows crafted Google login page with user account
We found the following attempts of exploitation of Google legitimate services by the malware author:
- Steal victim’s Google account and password
- Request password recovery for a specific account
- Set recovery email address when creating new Google account
An interesting element of the phishing attack is that the malware authors tried to set their own email as the recovery address on Google’s legitimate services. For example, when a user clicks on the new Google account creation link in the phishing page, the crafted link is opened with the malware author’s email address as a parameter of RecoveryEmailAddress.
Figure 11. The crafted JavaScript attempts to set recovery email address for new Google account creation.
Fortunately for end users, none of the above malicious attempts are successful. The parameter with the malware author’s email address is simply ignored at the account creation stage.
Trojan
In addition to the Google phishing page, when “Libfunc” function of the trojan (dropped by the fake plugin or downloaded from the server) is executed, the mobile phone is totally compromised. It receives commands from the following hardcoded list of C2 servers. The main functionality of the trojan is implemented in a function called “doMainProc()”. Please note that there are a few variants of the trojanwith different functionality but, overall, they are pretty much the same.
Figure 12. Hardcoded list of C2 servers
The geolocation of hardcoded C2 servers lookslike the following:
Figure 13. Location of C2 Servers
Inside doMainProc(), the trojan receives commands from the C2 server and calls appropriate handlers. Part of the switch block below gives us an idea of what type of commands this trojan supports.
Figure 14. Subset of command handlers implemented in the dropped trojan.
As you can see, it has all the functionality that a normal trojan has. Downloading, uploading and deleting files on the device, leaking information to a remote server and so on. The following table explains supported C2 commands:
Figure 15. C2 Commands
Before entering the command handling loop, the trojan does some initialization, like sending device information files to the server and checking the UID of the device. Only after the UID checking returns a 1 does it enter the loop.
Figure 16 Servers connected before entering command loop
Among these commands, directory indexing in particular is important. The directory structure is saved in a file named “kakao.property” and while indexing the given path in the user device, it checks the file with specific keywords and if it matches, uploads the file to the remote upload server. These keywords are Korean and its translated English version is as per the following table:
Figure 17 Search file keywords
By looking at the keywords we can anticipate that the malware authors were looking for files related to the military, politics and so on. These files are uploaded to a separate server.
Figure 18 Keyword matching file upload server
Conclusion
Applications can easily trick users into installing them before then leaking sensitive information. Also, it is not uncommon to see malware sneaking onto the official Google Play store, making it hard for users to protect their devices. This malware has not been written for ordinary phishing attempts, but rather very targeted attacks, searching the victim’s devices for files related to the military and politics, likely trying to leak confidential information. Users should always install applications that they can fully trust even though they are downloaded from trusted sources.
McAfee Mobile Security detects this threat as Android/MalBus and alerts mobile users if it is present, while protecting them from any data loss. For more information about McAfee Mobile Security, visit https://www.mcafeemobilesecurity.com.
Hashes (SHA-256)
Initial Downloader (APK)
• 19162b063503105fdc1899f8f653b42d1ff4fcfcdf261f04467fad5f563c0270
• bed3e665d2b5fd53aab19b8a62035a5d9b169817adca8dfb158e3baf71140ceb
• 3252fbcee2d1aff76a9f18b858231adb741d4dc07e803f640dcbbab96db240f9
• e71dc11e8609f6fd84b7af78486b05a6f7a2c75ed49a46026e463e9f86877801
Fake Plugin (APK)
• ecb6603a8cd1354c9be236a3c3e7bf498576ee71f7c5d0a810cb77e1138139ec
• b8b5d82eb25815dd3685630af9e9b0938bccecb3a89ce0ad94324b12d25983f0
Trojan (additional payload)
• b9d9b2e39247744723f72f63888deb191eafa3ffa137a903a474eda5c0c335cf
• 12518eaa24d405debd014863112a3c00a652f3416df27c424310520a8f55b2ec
• 91f8c1f11227ee1d71f096fd97501c17a1361d71b81c3e16bcdabad52bfa5d9f
• 20e6391cf3598a517467cfbc5d327a7bb1248313983cba2b56fd01f8e88bb6b9